package se.webbzon.boltzmann.hud;

import java.awt.Color;
import java.awt.image.ImageObserver;

import se.webbzon.boltzmann.item.AbstractItem;
import se.webbzon.boltzmann.player.Player;
import se.webbzon.oschi01.font.HorizontalAlignment;
import se.webbzon.oschi01.font.VerticalAlignment;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldcamera.WorldCameraDrawable;
import se.webbzon.oschi01.worldcamera.WorldCameraPane;
import se.webbzon.oschi01.worldobject.WorldObject;

public class TopBar extends WorldObject {
	
	// The 2-dimensional depth of the top bar
	private static final int depth = -1;
	
	// The number of steps until the top bar is hidden
	private static final int showTimeout = 120;
	
	// The player associated with this top bar
	private final Player player;
	
	// The layout of the top bar
	private final TopBarLayout layout;
	
	// Whatever the top bar is forced to be shown
	private boolean forceShow;
	
	// The counter for the top bar
	private int topBarCounter;
		
	// The y-position of the top bar
	private int topBarY;
	private final int topBarDy;
	
	// The image of the coin
	private volatile int coinImage;
	
	/*============================================================
	Constructors
	============================================================*/

	/** Creates a new game inventory top bar. **/
	public TopBar(Player player, TopBarLayout layout) {
		super(WorldObject.onStep + WorldObject.onPostDraw,depth);
		this.player = player;
		this.layout = layout;
		final ImageObserver o = player.getImageObserver();
		topBarDy = (int) (layout.getTopBarImage().getHeight(o)/7.0);
		
		forceShow = false;
		topBarCounter = 0;
		topBarY = -layout.getTopBarImage().getHeight(o);
		coinImage = 0;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Shows the top bar for a short period of time. **/
	public void show() {
		topBarCounter = showTimeout;
	}
	
	/** Sets whatever the top bar is forced to be shown permanently. **/
	public void setForceShow(boolean forceShow) {
		this.forceShow = forceShow;
	}
	
	/** Returns whatever the top bar is forced to be shown permanently. **/
	public boolean getForceShow() {
		return forceShow;
	}
	
	@Override public void onStep(WorldArea world) {
		final ImageObserver o = player.getImageObserver();
		final int height = layout.getTopBarImage().getHeight(o);
		
		// Show top bar permanently
		if (forceShow)
			topBarCounter = showTimeout;
		
		// Make the top bar dynamic
		if (topBarCounter > 0) {
			topBarCounter--;
			if (topBarY < 0)
				topBarY+=topBarDy;
		} else {
			if (topBarY > -height)
				topBarY-=topBarDy;
		}
		
		// Keep the top bar within the vertical range
		if (topBarY > 0)
			topBarY = 0;
		else if (topBarY < -height)
			topBarY = -height;
		
		if (coinImage == layout.getCharacterImageSet().size()-1)
			coinImage = 0;
		else
			coinImage++;
	}
	
	@Override public void onPostDraw(WorldArea world, WorldCameraPane hud) {
		// Draw background
		final int 	topBarX = layout.getXOffset();
		hud.drawImage(layout.getTopBarImage(), topBarX, topBarY);
		
		// Draw images
		drawItem(topBarX,topBarY,hud);
		drawCharacter(topBarX,topBarY,hud);
		drawCoinImage(topBarX,topBarY,hud);
		drawNoteImage(topBarX,topBarY,hud);
		drawHealthBar(topBarX,topBarY,hud);
		drawEnergyBarImage(topBarX,topBarY,hud);
		
		// Draw the texts
		hud.setFont(layout.getTextFont());
		hud.setColor(Color.black);
		hud.setHAlignment(HorizontalAlignment.LEFT);
		hud.setVAlignment(VerticalAlignment.BOTTOM);
		drawCoinText(topBarX,topBarY,hud);
		drawNoteText(topBarX,topBarY,hud);
		drawEnergyBarText(topBarX,topBarY,hud);
		
		hud.setColor(Color.white);
		drawCoinText(topBarX-1,topBarY-1,hud);
		drawNoteText(topBarX-1,topBarY-1,hud);
		drawEnergyBarText(topBarX-1,topBarY-1,hud);
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Draws the selected item in the top bar. **/
	private final void drawItem(int topBarX, int topBarY, WorldCameraPane hud) {
		final AbstractItem item = player.getSelectedItem();
		if (item != null) {
			final int 	itemX = topBarX+layout.getItemXOffset(),
						itemY = topBarY+layout.getItemYOffset(),
						itemWidth = layout.getItemWidth(),
						itemHeight = layout.getItemHeight();
			hud.drawImage(	item.getTextureSet().get(0).getImage(),
							itemX,itemY,itemWidth,itemHeight);
		}
	}
	
	/** Draws the selected character in the top bar. **/
	private final void drawCharacter(int topBarX, int topBarY, WorldCameraPane hud) {
		final int 	characterX = topBarX + layout.getCharacterXOffset(),
					characterY = topBarY + layout.getCharacterYOffset();
		hud.drawImage(layout.getCharacterImageSet().get(0), characterX, characterY);
	}
	
	/** Draws the coin image in the top bar. **/
	private final void drawCoinImage(int topBarX, int topBarY, WorldCameraPane hud) {
		final int	coinX = topBarX + layout.getCoinXOffset(),
					coinY = topBarY + layout.getCoinYOffset();
		hud.drawImage(layout.getCoinImageSet().get(coinImage), coinX, coinY);
	}
	
	/** Draws the coin text in the top bar. **/
	private final void drawCoinText(int topBarX, int topBarY, WorldCameraPane hud) {
		final String 	coinText = "x " + player.getCoins().getCoins();
		final ImageObserver o = hud.getImageObserver();
		final int coinWidth = layout.getCoinImageSet().get(0).getWidth(o);
		final int coinHeight = layout.getCoinImageSet().get(0).getHeight(o);
		final int coinTextX = topBarX + layout.getCoinXOffset() + coinWidth + layout.getCoinXSpacing();
		final int coinTextY = topBarY + layout.getCoinYOffset() + coinHeight;
		hud.drawString(coinText, coinTextX, coinTextY);
	}
	
	/** Draws the note image in the top bar. **/
	private final void drawNoteImage(int topBarX, int topBarY, WorldCameraPane hud) {
		final int	noteX = topBarX + layout.getNoteXOffset(),
					noteY = topBarY + layout.getNoteYOffset();
		hud.drawImage(layout.getNoteImageSet().get(0), noteX, noteY);
	}
	
	/** Draws the note text in the top bar. **/
	private final void drawNoteText(int topBarX, int topBarY, WorldCameraPane hud) {
		final String 	noteText = player.getLevel().getNotes() + "/" + player.getLevel().requiredNotes();
		final ImageObserver o = hud.getImageObserver();
		final int noteWidth = layout.getNoteImageSet().get(0).getWidth(o);
		final int noteHeight = layout.getNoteImageSet().get(0).getHeight(o);
		final int 		noteTextX = topBarX + 
									layout.getNoteXOffset() + 
									layout.getNoteXSpacing() + 
									noteWidth,
						noteTextY = topBarY + 
									layout.getNoteYOffset() + 
									noteHeight;
		hud.drawString(noteText, noteTextX, noteTextY);

	}
	
	/** Draws the health bar image in the top bar. **/
	private final void drawHealthBar(int topBarX, int topBarY, WorldCameraPane hud) {
		final int	healthBarX = topBarX + layout.getHealthBarXOffset(),
					healthBarY = topBarY + layout.getHealthBarYOffset(),
					healthBarXSpacing = layout.getHealthBarXSpacing();
		final int 	units = player.getHealth().getMaxUnits(),
					whole = player.getHealth().getUnits(),
					fractions = player.getHealth().getFractions();
		final ImageObserver o = hud.getImageObserver();
		final int healthBarWidth = layout.getHealthBarImageSet().get(0).getWidth(o);
		for (int i = 0; i < units; i ++) {
			int index;
			if (i < whole)
				index = 8;
			else if (i > whole)
				index = 0;
			else
				index = fractions;
			hud.drawImage(	layout.getHealthBarImageSet().get(index), 
							healthBarX + 
							i * (healthBarWidth + healthBarXSpacing), 
							healthBarY);
				
		}
	}
	
	/** Draws the energy bar in the top bar. **/
	private final void drawEnergyBarImage(int topBarX, int topBarY, WorldCameraPane hud) {
		final int	energyBarX = topBarX + layout.getEnergyBarXOffset(),
					energyBarY = topBarY + layout.getEnergyBarYOffset();
		hud.setColor(Color.black);
		hud.fillRect(energyBarX, energyBarY, layout.getEnergyBarWidth(), layout.getEnergyBarHeight());
		hud.setColor(Color.ORANGE);
		hud.fillRect(energyBarX-2, energyBarY-2, layout.getEnergyBarWidth()-256, layout.getEnergyBarHeight());
	}
	
	/** Draws the health bar text in the top bar. **/
	private final void drawEnergyBarText(int topBarX, int topBarY, WorldCameraPane hud) {
		final String 	energyBarText = player.getEnergy().getEnergy() + 
										"/" + 
										player.getEnergy().getMaxEnergy();
		final int 		energyBarTextX = 	topBarX + 
											layout.getEnergyBarXOffset(),
						energyBarTextY = 	topBarY + 
											layout.getEnergyBarYOffset() + 
											layout.getEnergyBarHeight() - 
											layout.getEnergyBarYSpacing();
		hud.drawString(energyBarText, energyBarTextX, energyBarTextY);
	}

}
